import os
import time
from tokenize import TokenError

from django.http import HttpResponse
from django.shortcuts import render
from rest_framework import status, serializers
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_simplejwt.exceptions import InvalidToken
from rest_framework_simplejwt.views import TokenObtainPairView

from buleking import settings
from utils.permissions import UserPermission
from .models import UserModel, AddressModel
from rest_framework.viewsets import ModelViewSet
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from .serializer import UserSerializer, AddressSerializer
from rest_framework.views import APIView
from django.contrib.auth.backends import BaseBackend
from django.db.models import Q
from rest_framework.permissions import IsAuthenticated
#from proj.celery_task import send



class MyBackend(BaseBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = UserModel.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))

        except UserModel.DoesNotExist:
            raise serializers.ValidationError("用户不存在")
        else:
            if user.check_password(password):
                return user
            else:
                raise serializers.ValidationError("密码错误")


class RegisterView(APIView):
    """
        {
        "username":"lzl",
        "phone":"15132061911",
        "password":"123456"
        }
    """

    def post(self, request):
        datas = request.data
        username = datas.get("username")
        password = datas.get("password")
        phone = datas.get("phone")
        email = datas.get("email", None)
        user = UserModel.objects.filter(username=username).exists()
        if user:
            return Response({"code": 20004, "msg": "user is exist"})
        user = UserModel.objects.create_user(username=username, password=password, phone=phone, email=email)
        # user = UserModel.objects.create_superuser(username=username, password=password, phone=phone, email=email)
        resp = {
            "id": user.id,
            "username": user.username,
            "email": user.email,
            "phone": user.phone,
        }
        return Response(resp)


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        print(attrs, "attrs")
        # 在此处添加自定义的数据
        data['user_id'] = self.user.id
        data['email'] = self.user.email
        data['username'] = self.user.username
        data['phone'] = self.user.phone
        data['token'] = data.pop("access")

        # 你可以根据需要添加其他数据
        # data['custom_message'] = "This is a custom response"

        return data


class CustomLoginView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer

    # def post(self, request: Request, *args, **kwargs) -> Response:
    #     serializer = self.get_serializer(data=request.data)
    #
    #     try:
    #         serializer.is_valid(raise_exception=True)
    #     except TokenError as e:
    #         raise InvalidToken(e.args[0])
    #     serializer.validated_data
    #
    #     return Response(serializer.validated_data, status=status.HTTP_200_OK)


# Create your views here.


def home(request):
    # celery -A proj.celery_tasks  worker -l info -P gevent
    start = time.time()
    user = UserModel.objects.get(username='bk')
    res = user.addresses.all()
    print(res)
    #res = send.delay(1, 2)
    print(res, "res")
    print(time.time() - start, "time")
    return HttpResponse("ok")


def arrange_task(request):
    #     user = UserModel.objects.get(username="django")
    #     flag = user.is_staff
    #     if flag == True:
    #         user.is_staff = False
    #         user.save()
    #     else:
    #         user.is_staff = True
    #         user.save()
    #     print(flag, "flag")
    return HttpResponse("ok")


class ProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"message": "This is a protected view"})


def test(request):
    """
    我想基于genericViewset的响应数据封装成统一的格式
    """
    return Response({"code": 200, "msg": "ok", "data": {}})


class MultipleDestroyMixin:

    @action(methods=["delete"], detail=False)
    def multiple_delete(self, request, *args, **kwargs):
        """
        批量删除
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        delete_ids = request.data.get("ids")
        if not delete_ids:
            return Response({"code": 2001, "msg": "请传入要删除的id列表"})
        if not isinstance(delete_ids, list):
            return Response({"code": 200, "msg": "不是列表"})
        queryset = self.get_queryset()
        del_queryset = queryset.filter(id__in=delete_ids)
        if del_queryset.count() != len(delete_ids):
            return Response({"code": 2004, "msg": "删除的id不存在"})
        del_queryset.delete()
        return Response({"code": 200, "msg": "删除成功"})


class UserViewSet(ModelViewSet, MultipleDestroyMixin):
    queryset = UserModel.objects.all()
    serializer_class = UserSerializer
    # permission_classes = []
    permission_classes = [IsAuthenticated, UserPermission]

    # 批量新增
    @action(methods=["POST"], detail=False)
    def bulk_create(self, request, *args, **kwargs):
        """
        {"users": [
            {"username": "bk", "password": "123456"},
            {"username": "lzz", "password": "123456"}
        ]}

        """
        data = request.data.get("users", None)
        ls = []
        for user in data:
            user_obj = UserModel.objects.create_user(**user)
            ls.append(user_obj.id)
        # users = UserModel.objects.bulk_create(ls)
        return Response(ls)

    @action(methods=["POST"], detail=False)
    def upload_avatar(self, request, *args, **kwargs):
        print(args, kwargs)
        images = request.data["avatar"]

        file_path = os.path.join(settings.MEDIA_ROOT, images.name)
        # F:\py_project\buleking\media
        max_size = 1024 * 300  # 300KB
        if images.size > max_size:
            return Response({"error": "File too large. Max size is 300KB."}, status=status.HTTP_400_BAD_REQUEST)
        with open(file_path, 'ab') as fp:
            for part in images.chunks():
                fp.write(part)
                fp.flush()  # 清空缓存

        return Response("头像上传成功")

    def finalize_response(self, request, response, *args, **kwargs):

        if isinstance(response, Response):
            # 封装新的响应结构
            response_data = {
                "code": 0,
                "data": response.data,
                "message": ""
            }
            # 将封装好的数据重新赋值给 response 的 data 属性
            response.data = response_data

        response = super().finalize_response(request, response, *args, **kwargs)

        return response

    # permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]


class AddressViewSet(ModelViewSet):
    queryset = AddressModel.objects.all()
    serializer_class = AddressSerializer


class AvatarViewSet(ModelViewSet):
    queryset = UserModel.objects.all()
    serializer_class = AddressSerializer
